﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Hopscotch.Domain.Finance;
using Hopscotch.Presentation.Common;
using Hopscotch.Presentation.Controls.Core;
using Hopscotch.Presentation.Controls.DataProviders;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using Hopscotch.Presentation.Common.Constants;

namespace Hopscotch.Presentation.Controls.Test
{
	[TestFixture, RequiresSTA]
	public class PriceControlTest
	{
		private PriceControl priceControl;
		private Mock<IPriceControlDataProvider> priceControlDataProviderMock;
		private List<CurrencyInstrument> currencyList;

		[SetUp]
		public void Setup()
		{
			priceControl = new PriceControl();
			priceControlDataProviderMock = new Mock<IPriceControlDataProvider>();

			currencyList = new List<CurrencyInstrument>() 
			{ 
				new CurrencyInstrument() { Code = "EUR" },
				new CurrencyInstrument() { Code = "GBP" },
				new CurrencyInstrument() { Code = "USD" }
				
			};
			priceControlDataProviderMock.Setup(x => x.GetCurrencyList()).Returns(currencyList);
		}

		[Test]
		public void TestSettingDataProviderLoadsCurrencyList()
		{
			priceControl.DataProvider = priceControlDataProviderMock.Object;

			priceControl.Currencies.Should().NotBeNull().And.HaveCount(currencyList.Count);
			priceControl.Currencies.Should().Contain(p => p.Code == "USD");
		}

		[Test]
		public void TestControlHasErrorIfDataProviderNotSet()
		{
			priceControl.HasErrors.Should().BeTrue();
			var errors = priceControl.GetErrors("Price");
			errors.Should().NotBeEmpty();
			errors.Should().HaveCount(1);
			foreach (DataErrorInfo error in errors)
			{
				error.ErrorType.Should().Be(ErrorType.Error);
				error.Description.Should().Be(ErrorMessages.DataProviderNotSetErrorMsg);
			}
		}

		[Test]
		public void TestSettingDataProviderRaisesErrorsChanged()
		{
			priceControl.HasErrors.Should().BeTrue();
			bool called = false;

			priceControl.ErrorsChanged += (s, e) => { called = true; };

			priceControl.DataProvider = priceControlDataProviderMock.Object;
			priceControl.HasErrors.Should().BeFalse();

			called.Should().BeTrue("ErrorsChanged not raised");
		}

		[Test]
		public void TestSettingCurrencySetsCurrencyCode()
		{
			priceControl.DataProvider = priceControlDataProviderMock.Object;

			priceControl.Currency.Should().BeNull();
			priceControl.CurrencyCode.Should().BeNull();

			priceControl.Currency = currencyList.FirstOrDefault(p => p.Code == "USD");
			priceControl.CurrencyCode.Should().Be("USD");
		}

		[Test]
		public void TestSettingCurrencyCodeSetsCurrency()
		{
			priceControl.DataProvider = priceControlDataProviderMock.Object;

			priceControl.Currency.Should().BeNull();
			priceControl.CurrencyCode.Should().BeNull();

			priceControl.CurrencyCode = "USD";
			priceControl.Currency.Should().NotBeNull();
			priceControl.Currency.Should().Equals(currencyList.FirstOrDefault(p => p.Code == "USD"));
		}

	}
}
